package net.pws.oos.web;

import java.io.File;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
import javax.imageio.stream.ImageInputStream;
import javax.servlet.ServletContext;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.pws.common.domain.BusinessException;
import net.pws.common.jackson.JsonUtils;
import net.pws.common.persistence.EntityManager;
import net.pws.common.poi.CellOverrider;
import net.pws.common.poi.CellOverriderFactory;
import net.pws.common.poi.PoiUtils;
import net.pws.common.security.SecurityContext;
import net.pws.common.simplemq.DataQueueProcessor;
import net.pws.common.util.DateUtils;
import net.pws.common.util.StringUtils;
import net.pws.oos.biz.bdmap.LocationData;
import net.pws.oos.biz.model.Attachment;
import net.pws.oos.biz.model.Dict;
import net.pws.oos.biz.model.IndicatorValue;
import net.pws.oos.biz.model.Organization;
import net.pws.oos.biz.model.Project;
import net.pws.oos.biz.model.ProspectRecod;
import net.pws.oos.biz.model.SupervisionRecod;
import net.pws.oos.biz.model.Task;
import net.pws.oos.biz.model.User;
import net.pws.oos.biz.query.AttachmentFinder;
import net.pws.oos.biz.query.DictFinder;
import net.pws.oos.biz.query.IndicatorFinder;
import net.pws.oos.biz.query.SupervFinder;
import net.pws.oos.biz.query.SystemManageFinder;
import net.pws.oos.biz.query.TaskFinder;
import net.pws.oos.biz.query.parameter.TaskQueryParameter;
import net.pws.oos.biz.query.parameter.TaskStatsByProjectQueryParameter;
import net.pws.oos.biz.service.MapService;
import net.pws.oos.biz.service.SupervService;
import net.pws.oos.biz.service.TaskService;
import net.pws.oos.biz.service.export.TaskExcelExportData;
import net.pws.oos.security.SecurityUtils;
import net.pws.oos.web.dto.AttachmentDto;
import net.pws.oos.web.dto.PhotoMarkerDto;
import net.pws.oos.web.dto.ProspectRecodDto;
import net.pws.oos.web.dto.SupervDto;
import net.pws.oos.web.dto.TaskDto;
import net.pws.oos.web.stats.StatsComputer;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.context.ServletContextAware;
import org.springframework.web.multipart.MultipartFile;

@Controller
@RequestMapping("/biz/task")
@SuppressWarnings("rawtypes")
public class TaskAction implements ServletContextAware {
    
    private final transient Log logger = LogFactory.getLog(TaskAction.class);
    
    private static final String WORD_TEMPLATE = "/template/Word";
    
    private static final String EXCEL_DOWNLOAD = "/temp";
    
    private static final int MAX_WORD_IMAGE = 8;
    
    private static final int JPG_MAX_WIDTH = 236;
    
    private static final int JPG_MAX_HEIGT = 200;
    
    private static final String SIMPLE_TIME_FORMAT = "yyyyMMddHHmmssSSS";
    
    @Autowired
    protected EntityManager entityManager;
    
    @Autowired
    private TaskService taskService;
    
    @Autowired
    private TaskFinder taskFinder;
    
    @Autowired
    private IndicatorFinder indicatorFinder;
    
    @Autowired
    private AttachmentFinder attachmentFinder;
    
    @Autowired
    private SystemManageFinder systemManageFinder;
    
    @Autowired
    private DictFinder dictFinder;
    
    @Autowired
    private MapService mapService;
    
    @Autowired
    private SupervFinder supervFinder;
    
    @Autowired
    private SupervService supervService;
    
    @Autowired
    @Qualifier("taskExcelExportProcessor")
    private DataQueueProcessor taskExcelExportProcessor;
    
    @Autowired
    @Qualifier("attachmentPath")
    private String attachmentPath;
    
    private ServletContext context;
    
    public void setServletContext(ServletContext context) {
        this.context = context;
    }
    
    
    @RequestMapping(value = "/importBrandSort.do", method = RequestMethod.POST)  
    public String importBrandSort(@RequestParam("filename") MultipartFile file,HttpServletRequest request,HttpServletResponse response,ModelMap map) throws Exception {  
        /*String temp = request.getSession().getServletContext() 
                .getRealPath(File.separator) 
                + "temp"; // 临时目录 
        File tempFile = new File(temp); 
        if (!tempFile.exists()) { 
            tempFile.mkdirs(); 
        } 
        DiskFileUpload fu = new DiskFileUpload(); 
        fu.setSizeMax(10 * 1024 * 1024); // 设置允许用户上传文件大小,单位:位 
        fu.setSizeThreshold(4096); // 设置最多只允许在内存中存储的数据,单位:位 
        fu.setRepositoryPath(temp); // 设置一旦文件大小超过getSizeThreshold()的值时数据存放在硬盘的目录 
        // 开始读取上传信息 
        // int index = 0; 
        List fileItems = null; 
        try { 
            fileItems = fu.parseRequest(request); 
        } catch (Exception e) { 
            e.printStackTrace(); 
        } 
        Iterator iter = fileItems.iterator(); // 依次处理每个上传的文件 
        FileItem fileItem = null; 
        while (iter.hasNext()) { 
            FileItem item = (FileItem) iter.next();// 忽略其他不是文件域的所有表单信息 
            if (!item.isFormField()) { 
                fileItem = item; 
                // index++; 
            } 
        } 
         
        if (fileItem == null) 
            return null; 
            */  
        if (file == null)  
            return null;  
        logger.info(file.getOriginalFilename());  
  
        String name = file.getOriginalFilename();// 获取上传文件名,包括路径  
        //name = name.substring(name.lastIndexOf("\\") + 1);// 从全路径中提取文件名  
        long size = file.getSize();  
        if ((name == null || name.equals("")) && size == 0)  
            return null;  
        InputStream in = file.getInputStream();
        StringBuffer errorMsg = new StringBuffer();  
        
        String configFilePath = request.getRealPath("/biz/task/import/excel_column.txt");
        logger.debug(String.format("配置文件路径：%s", configFilePath));
        taskService.importTask(in, configFilePath, errorMsg, SecurityUtils.currentUserId());
        // 改为人工刷新缓存KeyContextManager.clearPeriodCacheData(new  
        // PeriodDimensions());// 清理所有缓存  
        //int count = BrandMobileInfos.size();  
          
//            strAlertMsg= "成功更新" + count + "条！";  
        if(errorMsg.length() == 0){
        	errorMsg.append("导入成功！");
        }else{
        	logger.error(errorMsg.toString());  
        }
        //request.setAttribute("brandPeriodSortList", BrandMobileInfos);  
        //request.setAttribute("strAlertMsg", strAlertMsg);  
      
//        request.getSession().setAttribute("msg",strAlertMsg);  
//        return get(request, response);  
        
        map.put("msg", errorMsg.toString());
        //return null;  
        return "task/import/excel";
    }  
    
    /**
     * 派发任务管理页面
     * 
     * @return
     */
    @RequestMapping("/dispatches.do")
    public String dispatchesPage(ModelMap map) {
        Date today = new Date();
        Date firstDay = DateUtils.getFirstDay();
        String startDate = DateUtils.getDateStr(firstDay);
        String endDate = DateUtils.getDateStr(today);
        map.put("createStartDate", startDate);
        map.put("createEndDate", endDate);
        return "task/dispatches";
    }
    
    /**
     * 自主任务管理页面
     * 
     * @return
     */
    @RequestMapping("/selves.do")
    public String selvesPage(ModelMap map) {
        Date today = new Date();
        Date firstDay = DateUtils.getFirstDay();
        String startDate = DateUtils.getDateStr(firstDay);
        String endDate = DateUtils.getDateStr(today);
        map.put("locateStartDate", startDate);
        map.put("locateEndDate", endDate);
        map.put("execPersonId", SecurityUtils.currentUserId());
        return "task/selves";
    }
    
    @RequestMapping("/list.json")
    @ResponseBody
    public Object getTaskList(TaskQueryParameter param) {
        param = initParametersByRole(param);
        
        return listTasks(param);
    }
    
    private TaskQueryParameter initParametersByRole(TaskQueryParameter param) {
        if (param == null) {
            param = new TaskQueryParameter();
        }
        
        if (StringUtils.areBlank(param.getExecPersonId(),
                                 param.getExecOrganId())) {
            if (SecurityUtils.isManager()) {
                param.setExecOrganId(SecurityUtils.currentUser().getOrganId());
            }
            else {
                param.setExecPersonId(SecurityUtils.currentUserId());
            }
        }
        return param;
    }
    
    private Object listTasks(TaskQueryParameter param) {
        try {
            List<Map> tasks = taskFinder.getTaskList(param,
                                                     param.getStart(),
                                                     param.getLimit());
            return JsonUtils.succeedMap(tasks);
        }
        catch (Exception e) {
            logger.error(e, e);
            return JsonUtils.failedMap(e.getMessage());
        }
    }
    
    @RequestMapping("/count.json")
    @ResponseBody
    public Object getTaskCount(TaskQueryParameter param) {
        param = initParametersByRole(param);
        return countTasks(param);
    }
    
    private Object countTasks(TaskQueryParameter param) {
        try {
            return JsonUtils.succeedMap(taskFinder.countTask(param));
        }
        catch (Exception e) {
            logger.error(e, e);
            return JsonUtils.failedMap(e.getMessage());
        }
    }
    
    @RequestMapping("/edit.do")
    public String editPage(String id, ModelMap map) {
        if (StringUtils.isEmpty(id)) {
            return "task/new";
        }

        Task task = taskFinder.getTaskMap(id);
        map.put("data", TaskDto.from(task));
        
        map.put("stationTypes", indicatorFinder.getIndicatorValueListByIndicatorProp("stationType"));
        map.put("sitePropertiess", indicatorFinder.getIndicatorValueListByIndicatorProp("siteProperties"));
        map.put("propertyOwnerships", indicatorFinder.getIndicatorValueListByIndicatorProp("propertyOwnership"));
        map.put("areaTypes", indicatorFinder.getIndicatorValueListByIndicatorProp("areaType"));
        map.put("constructionModels", indicatorFinder.getIndicatorValueListByIndicatorProp("constructionModel"));
        map.put("siteValids", indicatorFinder.getIndicatorValueListByIndicatorProp("siteValid"));
        
        return "task/edit";
    }
    
    @RequestMapping("/detail.do")
    public String detailPage(String id, ModelMap map) {
        map.put("id", id);
        return "task/detail";
    }
    
    @RequestMapping("/detail.json")
    @ResponseBody
    public Object getTaskDetail(String id) {
        if (StringUtils.isEmpty(id)) {
            return JsonUtils.failedMap("错误的参数！");
        }
        
        Task task = taskFinder.getTaskMap(id);
        if (task == null) {
            return JsonUtils.failedMap("您查找的任务不存在！");
        }
        
        return JsonUtils.succeedMap(TaskDto.from(task));
    }
    
    @RequestMapping("/save.json")
    @ResponseBody
    public Object saveTask(TaskDto dto) {
        try {
            Task task = null;
            if (StringUtils.isNotEmpty(dto.getId())) {
                task = taskFinder.getTask(dto.getId());
            }
            if (task == null) {
                task = new Task();
            }
            
            task = TaskDto.to(task, dto, entityManager);
            if (StringUtils.isBlank(task.getStatus())) {
                task.setStatus(Task.ASSIGNED_STATUS);
            }
            if (task.getCreateDateTime() == null) {
                task.setCreateDateTime(new Date());
            }
            if (task.getCreator() == null) {
                task.setCreator(entityManager.find(User.class,
                                                   SecurityUtils.currentUserId()));
            }
            if (task.getAssignedDate() == null) {
                task.setAssignedDate(new Date());
            }
            
            taskService.saveTask(task);
            
            if(task.getProspectRecod() == null){
            	ProspectRecod prospectRecod = new ProspectRecod(task);
                entityManager.persist(prospectRecod);
				task.setProspectRecod(prospectRecod);
            }
            
            return getTaskDetail(task.getId());
//             return JsonUtils.succeedMap(TaskDto.from(task));
        }
        catch (Exception e) {
            logger.error(e, e);
            return JsonUtils.failedMap(e.getMessage());
        }
    }
    
    @RequestMapping("/delete.json")
    @ResponseBody
    public Object deleteTask(String id) {
        Task task = taskFinder.getTask(id);
        if (task == null) {
            return JsonUtils.succeedMap(id);
        }
        
        if (!(Task.DRAFT_STATUS.equals(task.getStatus()) || Task.ASSIGNED_STATUS.equals(task.getStatus()))) {
            return JsonUtils.failedMap("您要删除的任务不是草稿状态！");
        }
        
        if ((task.getCreator() == null) || !task.getCreator()
                                                .getId()
                                                .equals(SecurityContext.getContext()
                                                                       .getId())) {
            return JsonUtils.failedMap("您不是该任务的创建人员，无权限删除该任务！");
        }
        
        try {
            entityManager.remove(task);
            return JsonUtils.succeedMap(id);
        }
        catch (Exception e) {
            logger.error(e, e);
            return JsonUtils.failedMap(e.getMessage());
        }
    }
    
    @RequestMapping("/cleanAddress.json")
    @ResponseBody
    public Object cleanAddress(String id) {
        Task task = taskFinder.getTask(id);
        if (task == null) {
            return JsonUtils.failedMap("任务不存在！");
        }
        
        // 清空地址
        task.setLocationProvice(null);
        task.setLocationCity(null);
        task.setLocationCounty(null);
        task.setLocationStreet(null);
        task.setLocationNumber(null);
        task.setLocationAddress(null);

        LocationData location = null;
        try {
            location = mapService.getAddress(task.getLongitude(), task.getLatitude());
        }
        catch (Exception e) {
            logger.error(e, e);
        }
        
        if (location != null) {
            task.setLocationAddress(location.getLocationAddress());
            task.setLocationProvice(location.getLocationProvice());
            task.setLocationCity(location.getLocationCity());
            task.setLocationCounty(location.getLocationCounty());
            task.setLocationStreet(location.getLocationStreet());
            task.setLocationNumber(location.getLocationNumber());
        }
        
        try {
            taskService.saveTask(task);
            return JsonUtils.succeedMap(id);
        }
        catch (Exception e) {
            logger.error(e, e);
            return JsonUtils.failedMap(e.getMessage());
        }
    }
    
    @RequestMapping("/attachment/list.json")
    @ResponseBody
    public Object getAttachmentList(String resourceId) {
        if (StringUtils.isBlank(resourceId)) {
            return JsonUtils.failedMap("未指定任务！");
        }
        
        List<Attachment> list = attachmentFinder.getPhotos(resourceId);
        List<AttachmentDto> dtos = new ArrayList<AttachmentDto>();
        for (Attachment att : list) {
            dtos.add(AttachmentDto.from(att));
        }
        return JsonUtils.succeedMap(dtos);
    }
    
    /**
     * 修改attachment描述信息
     * 
     * @return
     */
    @RequestMapping("/attachment/updateDescription.json")
    @ResponseBody
    public Object viewPhoto(AttachmentDto attachmentDto) {
    	if (StringUtils.isEmpty(attachmentDto.getId())) {
            return JsonUtils.failedMap("错误的参数！");
        }
        try {
        	Attachment photo = entityManager.find(Attachment.class, attachmentDto.getId());
        	photo.setDescription(attachmentDto.getDescription());
        	entityManager.persist(photo);
            return JsonUtils.succeedMap(photo.getId());
        }
        catch (Exception e) {
            logger.error(e, e);
            return JsonUtils.failedMap(e.getMessage());
        }
    }
    
    /**
     * 导出至WORD
     * 
     * @return
     */
    @RequestMapping("/word.do")
    public String exportWord(String id, HttpServletResponse response) {
        if (StringUtils.isEmpty(id)) {
            throw new BusinessException("错误的参数！");
        }
        
        Task task = taskFinder.getTaskMap(id);
        if (task == null) {
            throw new BusinessException("您查找的任务不存在！");
        }
        
//        List<SupervisionRecod> list = supervFinder.getSubSupervListByTask(id);
//        if(list.size() == 0){
//        	throw new BusinessException("您查找的任务还未填报项目情况，请先填报后再导出！");
//        }        
//        SupervisionRecod superv = list.get(0);
        
        List<Attachment> attachments = attachmentFinder.getPhotos(id);
        
        // 封装数据
        Map<String, CellOverrider> data = new HashMap<String, CellOverrider>();
        data.put("locateDate",
                 CellOverriderFactory.createText("日期：" + DateUtils.getDateStrCnWithWeek(task.getLocateDate())));
        data.put("locationAddress",
                 CellOverriderFactory.createText(task.getLocationAddress()));
        data.put("description",
                 CellOverriderFactory.createText(task.getDescription()));
        data.put("name", CellOverriderFactory.createText(task.getName()));
        Project project = task.getProject();
        if (project == null) {
            data.put("projectName",
                     CellOverriderFactory.createText(""));
            
        } else {
            data.put("projectName",
                     CellOverriderFactory.createText(project.getName()));            
        }
        
        //项目情况
//        data.put("constructionUnit", CellOverriderFactory.createText(superv.getConstructionUnit()));
//        data.put("constructionCase", CellOverriderFactory.createText(superv.getConstructionCase()));
//        data.put("constructionQuality", CellOverriderFactory.createText(superv.getConstructionQuality()));
//        data.put("constructionSafetyCulture", CellOverriderFactory.createText(superv.getConstructionSafetyCulture()));
//        data.put("otherSituations", CellOverriderFactory.createText(superv.getOtherSituations()));
//        data.put("rectificationMeasures", CellOverriderFactory.createText(superv.getRectificationMeasures()));
//        data.put("recordDate",
//                CellOverriderFactory.createText("日期：" + DateUtils.getDateStrCn(superv.getRecordDate())));
        
        if(null != task.getStationType()){
        	data.put("stationTypeName", CellOverriderFactory.createText(task.getStationType().getName()));
        }else{
        	data.put("stationTypeName", CellOverriderFactory.createText(""));
        }
        data.put("baseStationName", CellOverriderFactory.createText(task.getBaseStationName()));
        data.put("baseStationCode", CellOverriderFactory.createText(task.getBaseStationCode()));
        data.put("mainSeparation", CellOverriderFactory.createText(task.getMainSeparation()));
        if(null != task.getSiteProperties()){
        	data.put("sitePropertiesName", CellOverriderFactory.createText(task.getSiteProperties().getName()));
        }else{
        	data.put("sitePropertiesName", CellOverriderFactory.createText(""));
        }
        if(null != task.getPropertyOwnership()){
        	data.put("propertyOwnershipName", CellOverriderFactory.createText(task.getPropertyOwnership().getName()));
        }else{
        	data.put("propertyOwnershipName", CellOverriderFactory.createText(""));
        }
        if(null != task.getAreaType()){
        	data.put("areaTypeName", CellOverriderFactory.createText(task.getAreaType().getName()));
        }else{
        	data.put("areaTypeName", CellOverriderFactory.createText(""));
        }
        if(null != task.getConstructionModel()){
        	data.put("constructionModelName", CellOverriderFactory.createText(task.getConstructionModel().getName()));
        }else{
        	data.put("constructionModelName", CellOverriderFactory.createText(""));
        }
        data.put("projectPeriods", CellOverriderFactory.createText(task.getProjectPeriods()));
        data.put("content", CellOverriderFactory.createText(task.getContent()));
        
        
        String templatePath = getTemplate(attachments, data);
        
        try {
            XWPFDocument document = PoiUtils.replace(templatePath, data);
            response.reset(); // 清空buffer
            response.setContentType("application/vnd.openxmlformats-officedocument.wordprocessingml.document");
            response.setHeader("Content-Disposition",
                               "attachment; filename=" + new String(task.getName()
                                                                        .getBytes(),
                                                                    "iso8859-1")
                                       + ".docx");// 定义文件名
            response.setHeader("Pragma", "no-cache");
            response.setHeader("Expires", " 0");
            ServletOutputStream fOut = response.getOutputStream();
            document.write(fOut);
            fOut.flush();
            fOut.close();
        }
        catch (Exception e) {
            logger.error(e, e);
        }
        
        return null;
    }
    
    private String getTemplate(List<Attachment> attachments,
                               Map<String, CellOverrider> data) {
        int size = 2;
        int imageSize = attachments.size();
        if (imageSize > size) {
            size = MAX_WORD_IMAGE;
        }
        
        for (int i = 1; i <= size; i++) {
            if (i > imageSize) {
                data.put("photo" + i, CellOverriderFactory.createText(""));
                data.put("photoDescription" + i,
                         CellOverriderFactory.createText(""));
            }
            else {
                Attachment attachment = attachments.get(i - 1);
                String realPath = getAttachmentRoot() + "/"
                                  + attachment.getOrgiUri();
                data.put("photo" + i,
                         CellOverriderFactory.createJpg(realPath,
                                                        JPG_MAX_WIDTH,
                                                        JPG_MAX_HEIGT));
                data.put("photoDescription" + i,
                         CellOverriderFactory.createText(attachment.getDescription()));
            }
        }
        
        return context.getRealPath(WORD_TEMPLATE + size + ".docx");
    }
    
    // @RequestMapping("/excel1.do")
    // @Deprecated
    // public String exportExcel1(TaskQueryParameter parameter, ModelMap map,
    // HttpServletRequest request, HttpServletResponse response) {
    // parameter = initParametersByRole(parameter);
    // List<Map> tasks = taskFinder.getTaskList(parameter, 0,
    // Integer.MAX_VALUE);
    // for (Map task : tasks) {
    // String taskId = (String) task.get("id");
    // List<Attachment> attachments = attachmentFinder.getPhotos(taskId);
    // task.put("attachments", attachments);
    // }
    // map.put("tasks", tasks);
    // map.put("root",
    // "http://" + request.getServerName() + ":"
    // + request.getServerPort() + context.getContextPath()
    // + Attachment.ATTACHMENT_ROOT + "/");
    // return "/task/excel";
    // }
    
    @RequestMapping("/excel.json")
    @ResponseBody
    public Object exportExcel(TaskQueryParameter parameter) {
        try {
            parameter = initParametersByRole(parameter);
            TaskExcelExportData data = new TaskExcelExportData();
            data.setQueryParameter(parameter);
            data.setAttachmentRoot(getAttachmentRoot());
            
            User user = SecurityUtils.currentUser();
            StringBuilder excelUri = new StringBuilder(EXCEL_DOWNLOAD);
            excelUri.append("/")
                    .append("TaskExport_")
                    .append(user.getAccount())
                    .append("_")
                    .append(DateUtils.getDateStr(data.getCreateTime(),
                                                 SIMPLE_TIME_FORMAT))
                    .append(".xlsx");
            data.setExcelUri(excelUri.toString());
            data.setExcelPath(context.getRealPath(data.getExcelUri()));
            data.setUserId(user.getId());
            taskExcelExportProcessor.getDataPipe().addLazyData(data, 1);
            return JsonUtils.succeedMap(null);
        }
        catch (Exception e) {
            logger.error("AddTaskExcelExport error", e);
            return JsonUtils.failedMap(e.getMessage());
        }
    }
    
    /**
     * 任务查询页面
     * 
     * @return
     */
    @RequestMapping("/query.do")
    public String queryPage(TaskQueryParameter parameter, ModelMap map) {
        Date today = new Date();
        Date firstDay = DateUtils.getFirstDay();
        
        String startDate = null;
        if (parameter.getLocateStartDate() == null) {
            startDate = DateUtils.getDateStr(firstDay);
        }
        else {
            startDate = DateUtils.getDateStr(parameter.getLocateStartDate());
        }
        
        String endDate = null;
        if (parameter.getLocateEndDate() == null) {
            endDate = DateUtils.getDateStr(today);
        }
        else {
            endDate = DateUtils.getDateStr(parameter.getLocateEndDate());
        }
        
        String projectId = "";
        String projectName = "";
        if (StringUtils.isNotBlank(parameter.getProjectId())) {
            Project project = entityManager.find(Project.class,
                                                 parameter.getProjectId());
            if (project != null) {
                projectId = project.getId();
                projectName = project.getName();
            }
        }
        
        map.put("locateStartDate", startDate);
        map.put("locateEndDate", endDate);
        map.put("projectId", projectId);
        map.put("projectName", projectName);
        return "task/query";
    }
    
    @RequestMapping("/map.do")
    public String mapPage(TaskQueryParameter parameter, ModelMap map) {
        queryPage(parameter, map);
        return "task/map";
    }
    
    /**
     * 任务统计页面
     * 
     * @return
     */
    @RequestMapping("/statistics.do")
    public String statisticsPage(ModelMap map) {
        Date today = new Date();
        Date firstDay = DateUtils.getFirstDay();
        String startDate = DateUtils.getDateStr(firstDay);
        String endDate = DateUtils.getDateStr(today);
        map.put("locateStartDate", startDate);
        map.put("locateEndDate", endDate);
        return "task/statistics";
    }
    
    @RequestMapping("/statistics/excel.do")
    public String exportStatisticsExcel(TaskQueryParameter param, ModelMap map) {
        param = initParametersByRole(param);
        param.setStart(0);
        param.setLimit(Integer.MAX_VALUE);
        param.setStatus(Task.COMPLETED_STATUS);
        
        // 获得用户
        List<Map> users = taskFinder.getStatsUserList(param);
        if (users != null && users.size() > 0) {
            // 获得所有任务
            List<Map> tasks = taskFinder.getTaskList(param,
                                                     0,
                                                     Integer.MAX_VALUE);
            StatsComputer statsComputer = new StatsComputer(users, tasks);
            users = statsComputer.computeStats();
        }
        
        map.put("users", users);
        return "/task/statistics_excel";
    }
    
    @RequestMapping("/statistics/list.json")
    @ResponseBody
    public Object getStatsList(TaskQueryParameter param) {
        param = initParametersByRole(param);
        param.setStatus(Task.COMPLETED_STATUS);
        
        // 获得用户
        List<Map> users = taskFinder.getStatsUserList(param);
        if (users == null || users.isEmpty()) {
            return JsonUtils.succeedMap(users);
        }
        
        // 获得所有任务
        param.setExecPersonIds(getUserIns(users));
        List<Map> tasks = taskFinder.getTaskList(param, 0, Integer.MAX_VALUE);
        
        StatsComputer statsComputer = new StatsComputer(users, tasks);
        return JsonUtils.succeedMap(statsComputer.computeStats());
    }
    
    private String getUserIns(List<Map> users) {
        StringBuilder sb = new StringBuilder();
        for (Map user : users) {
            if (sb.length() > 0) {
                sb.append(",");
            }
            sb.append("'").append(user.get("id")).append("'");
        }
        
        return sb.toString();
    }
    
    @RequestMapping("/statistics/count.json")
    @ResponseBody
    public Object getStatsCount(TaskQueryParameter param) {
        param = initParametersByRole(param);
        param.setStatus(Task.COMPLETED_STATUS);
        return JsonUtils.succeedMap(taskFinder.countStatsUser(param));
    }
    
    /*
     * ------------------------------- 基于项目的任务统计 -------------------------------
     */
    
    @RequestMapping("/project/list.do")
    public String projectStatsPage(ModelMap map) {
        Date today = new Date();
        Date firstDay = DateUtils.getFirstDay();
        String startDate = DateUtils.getDateStr(firstDay);
        String endDate = DateUtils.getDateStr(today);
        map.put("locateStartDate", startDate);
        map.put("locateEndDate", endDate);
        
        map.put("organs", findOwnerCompanies());
        map.put("customers", dictFinder.listDicts(Dict.CUSTOMER));
        map.put("specials", dictFinder.listDicts(Dict.SPECIAL));
        return "task/project/list";
    }
    
    @RequestMapping("/project/excel.do")
    public String projectStatsExport(TaskStatsByProjectQueryParameter param,
                                     ModelMap map) {
        param = initQueryParams(param);
        param.setStart(0);
        param.setLimit(Integer.MAX_VALUE);
        List<Map> list = taskFinder.listStats(param);
        map.put("list", list);
        return "task/project/excel";
    }
    
    @RequestMapping("/project/count.json")
    @ResponseBody
    public Object projectStatsCount(TaskStatsByProjectQueryParameter param) {
        param = initQueryParams(param);
        return JsonUtils.succeedMap(taskFinder.countStats(param));
    }
    
    @RequestMapping("/project/list.json")
    @ResponseBody
    public Object projectStatsList(TaskStatsByProjectQueryParameter param) {
        param = initQueryParams(param);
        return JsonUtils.succeedMap(taskFinder.listStats(param));
    }
    
    private TaskStatsByProjectQueryParameter initQueryParams(TaskStatsByProjectQueryParameter queryParams) {
        if (queryParams == null) {
            queryParams = new TaskStatsByProjectQueryParameter();
        }
        
        if (StringUtils.isBlank(queryParams.getOrganId())) {
            Organization organ = findCurrentCompany();
            if (organ != null) {
                queryParams.setOrganId(organ.getId());
            }
        }
        return queryParams;
    }
    
    // 得到分公司
    private Organization findCurrentCompany() {
        String organId = SecurityUtils.currentUser().getOrganId();
        return systemManageFinder.getDepthOrganization(organId, 1);
    }
    
    // 得到分公司列表
    private List<Organization> findOwnerCompanies() {
        Organization organ = findCurrentCompany();
        if (organ != null) {
            List<Organization> list = new ArrayList<Organization>();
            list.add(organ);
            return list;
        }
        
        List<Organization> tops = systemManageFinder.getOrganizationChildren(null);
        return systemManageFinder.getOrganizationChildren(tops.get(0).getId());
    }
    
    /**
     * 得到文件系统中附件根目录的绝对路径
     * 
     * @return
     */
    private String getAttachmentRoot() {
        if (StringUtils.isBlank(attachmentPath)) {
            attachmentPath = context.getRealPath(Attachment.ATTACHMENT_ROOT);
        }
        return attachmentPath;
    }
    
    @RequestMapping("/toAssigned.json")
    @ResponseBody
    public Object toAssigned(String id) {
        if (StringUtils.isBlank(id)) {
            return JsonUtils.failedMap("找不到相应的任务！");
        }
        
        Task task = taskFinder.getTask(id);
        if (task == null) {
            return JsonUtils.failedMap("找不到相应的任务！");
        }
        
        if (!Task.IN_PROGRESS_STATUS.equals(task.getStatus())) {
            return JsonUtils.failedMap("对应的任务状态不正确！");
        }
        
        task.setStatus(Task.ASSIGNED_STATUS);
        taskService.saveTask(task);
        return JsonUtils.succeedMap(id);
    }
    
    @RequestMapping("/toProgress.json")
    @ResponseBody
    public Object toProgress(String id) {
        if (StringUtils.isBlank(id)) {
            return JsonUtils.failedMap("找不到相应的任务！");
        }
        
        Task task = taskFinder.getTask(id);
        if (task == null) {
            return JsonUtils.failedMap("找不到相应的任务！");
        }
        
        if (!Task.ASSIGNED_STATUS.equals(task.getStatus())) {
            return JsonUtils.failedMap("对应的任务状态不正确！");
        }
        
        if (task.getStartDate() == null) {
            return JsonUtils.failedMap("对应的任务状态不正确！");
        }
        
        task.setStatus(Task.IN_PROGRESS_STATUS);
        taskService.saveTask(task);
        return JsonUtils.succeedMap(id);
    }
    
    /**
     * 任务查询页面
     * 
     * @return
     */
    @RequestMapping("/photo.do")
    public String viewPhoto(String id, ModelMap map) {
        Attachment photo = entityManager.find(Attachment.class, id);
        map.put("description", photo.getDescription());
        map.put("path", photo.getOrgiUri());
        
        // 得到照片长宽
        String realPath = getAttachmentRoot() + "/" + photo.getOrgiUri();
        Iterator<ImageReader> readers = ImageIO.getImageReadersByFormatName("jpg");
        ImageReader reader = readers.next();
        File file = new File(realPath);
        try {
            ImageInputStream input = ImageIO.createImageInputStream(file);
            reader.setInput(input, true);
            int width = reader.getWidth(0);
            int height = reader.getHeight(0);
            map.put("width", width);
            map.put("height", height);
            input.close();
        }
        catch (Exception e) {
            logger.error("获取照片长宽", e);
        }
        
        List<PhotoMarkerDto> markers = PhotoMarkerDto.from(attachmentFinder.getPhotoMarkers(id));
        map.put("markers", markers);
        
        return "task/photo";
    }
    
    @RequestMapping("/superv/save.json")
    @ResponseBody
    public Object saveSuperv(SupervDto dto) {
        try {
        	SupervisionRecod superv = null;
            if (StringUtils.isNotEmpty(dto.getId())) {
            	superv = supervFinder.getSuperv(dto.getId());
            }
            if (superv == null) {
            	superv = new SupervisionRecod();
            }
            
            superv = SupervDto.to(superv, dto, entityManager);
            
            //if (superv.getRecordDate() == null) {
            	superv.setRecordDate(new Date());
            //}
            
            supervService.saveSuperv(superv);
            
            
            Task task = null;
            if (StringUtils.isNotEmpty(dto.getTaskId())) {
                task = taskFinder.getTask(dto.getTaskId());
            }
            if (task == null) {
            	return JsonUtils.failedMap("错误的参数！");
            }
            
            task.setContent(dto.getTaskContentOfTask());
            task.setDescription(dto.getTaskDescriptionOfTask());
            
            taskService.saveTask(task);
            
            return getSupervDetail(superv.getId());
        }
        catch (Exception e) {
            logger.error(e, e);
            
            return JsonUtils.failedMap(e.getMessage());
        }
    }
    
    @RequestMapping("/superv/detail.json")
    @ResponseBody
    public Object getSupervDetail(String id) {
        if (StringUtils.isEmpty(id)) {
            return JsonUtils.failedMap("错误的参数！");
        }
        try {
        	SupervisionRecod superv = supervFinder.getSuperv(id);
            if (superv == null) {
                return JsonUtils.failedMap("您查找的项目情况不存在！");
            }
            
            return JsonUtils.succeedMap(SupervDto.from(superv));
        }    
	    catch (Exception e) {
	    	logger.error(e, e);
            return JsonUtils.failedMap(e.getMessage());
		}    
        
    }
    
    @RequestMapping("/superv/list.json")
    @ResponseBody
    public Object getSupervByTask(String taskId) {
        if (StringUtils.isBlank(taskId)) {
            return JsonUtils.failedMap("未指定任务！");
        }
        SupervisionRecod superv = new SupervisionRecod();
        try {
	        List<SupervisionRecod> list = supervFinder.getSubSupervListByTask(taskId);
	        if(list.size() > 0){
	        	superv = list.get(0);
	        }        
	        return JsonUtils.succeedMap(SupervDto.from(superv));
        }    
	    catch (Exception e) {
	    	logger.error(e, e);
            return JsonUtils.failedMap(e.getMessage());
		}    
    }

    @RequestMapping("prospect/detail.json")
    @ResponseBody
    public Object getProspectDetail(String id, String taskId) {
    	ProspectRecod prospectRecod;
    	if (StringUtils.isEmpty(id)) {
    		prospectRecod = taskFinder.getProspectMapByTaskId(taskId);
    	}else{
    		prospectRecod = taskFinder.getProspectMapById(id);
    	}
    	
        if (prospectRecod == null) {
            return JsonUtils.failedMap("您查找的任务不存在！");
        }
        
        ProspectRecodDto dto = ProspectRecodDto.from(prospectRecod, entityManager);
		return JsonUtils.succeedMap(dto);
    }
    
    @RequestMapping("prospect/save.json")
    @ResponseBody
    public Object saveProspect(ProspectRecodDto dto) {
        try {
        	ProspectRecod prospect = null;
            if (StringUtils.isNotEmpty(dto.getId())) {
            	prospect = entityManager.find(ProspectRecod.class, dto.getId());
            }
            if (prospect == null) {
            	return JsonUtils.failedMap("错误的参数！");
            }
            
            prospect = ProspectRecodDto.to(prospect, dto, entityManager);
            
            entityManager.persist(prospect);
            return getProspectDetail(prospect.getId(), null);
        }
        catch (Exception e) {
            logger.error(e, e);
            
            return JsonUtils.failedMap(e.getMessage());
        }
    }
}
